import irrlicht;
import std.stdio;

class MyEventReceiver : IEventReceiver
{
    override bool OnEvent(SEvent event)
    {
        if(event.EventType == EEVENT_TYPE.EET_KEY_INPUT_EVENT)
        {
            KeyIsDown[event.KeyInput.Key] = event.KeyInput.PressedDown;
        }
        return false;
    }
    
    bool IsKeyDown(EKEY_CODE keyCode) const
    {
        return KeyIsDown[keyCode];
    }
    
    this()
    {
        for(uint i = 0; i<EKEY_CODE.KEY_KEY_CODES_COUNT; ++i)
            KeyIsDown[i] = false;
    }
    
    private bool[EKEY_CODE.KEY_KEY_CODES_COUNT] KeyIsDown;
}

void main()
{
    E_DRIVER_TYPE driverType;
	writeln("Please select the driver you want for this example:\n"~
			" (a) Direct3D 9.0c\n (b) Direct3D 8.1\n (c) OpenGL 1.5\n"~
			" (d) Software Renderer\n (e) Burning's Software Renderer\n"~
			" (f) NullDevice\n (otherKey) exit\n\n");
			
	switch(readln()[0])
	{
		case 'a': driverType = E_DRIVER_TYPE.EDT_DIRECT3D9;break;
		case 'b': driverType = E_DRIVER_TYPE.EDT_DIRECT3D8;break;
		case 'c': driverType = E_DRIVER_TYPE.EDT_OPENGL;break;
		case 'd': driverType = E_DRIVER_TYPE.EDT_SOFTWARE;break;
		case 'e': driverType = E_DRIVER_TYPE.EDT_BURNINGSVIDEO;break;
		case 'f': driverType = E_DRIVER_TYPE.EDT_NULL;break;
		default: assert(0, "No driver selected.");
	}
    
    MyEventReceiver receiver = new MyEventReceiver();

	IrrlichtDevice device = createDevice(driverType, new UintDimension2D(640, 480), 16, false, false, false, receiver);
	assert(device, "Unable to create device.");
	
	//scope(exit)clear(device);  ??
	
	IVideoDriver driver = device.getVideoDriver();
	ISceneManager smgr = device.getSceneManager();
    
    ISceneNode node = smgr.addSphereSceneNode();
    if(node)
    {
        node.setPosition(new FloatVector3D(0,0,30));
        node.setMaterialTexture(0, driver.getTexture("media/wall.bmp"));
        node.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, false);
    }
    
    ISceneNode n = smgr.addCubeSceneNode();
    if(n)
    {
        n.setMaterialTexture(0, driver.getTexture("media/t351sml.jpg"));
        n.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, false);
        ISceneNodeAnimator anim = 
            smgr.createFlyCircleAnimator(new FloatVector3D(0,0,30), 20.0);
        if(anim)
        {
            n.addAnimator(anim);
        }
    }
    
    IAnimatedMeshSceneNode anms = 
        smgr.addAnimatedMeshSceneNode(smgr.getMesh("media/ninja.b3d"));
    if(anms)
    {
        ISceneNodeAnimator anim =
            smgr.createFlyStraightAnimator(new FloatVector3D(100,0,60),
                                           new FloatVector3D(-100,0,60),
                                           3500,
                                           true);
        if(anim)
        {
            anms.addAnimator(anim);
        }
        anms.setMaterialFlag(E_MATERIAL_FLAG.EMF_LIGHTING, false);
        
        anms.setFrameLoop(0, 13);
        anms.setAnimationSpeed(15);
        //anms.setMD2Animation(EMD2_ANIMATION_TYPE.EMAT_RUN);
        
        anms.setScale(new FloatVector3D(2.0, 2.0, 2.0));
        anms.setRotation(new FloatVector3D(0, -90, 0));
    }
    
    smgr.addCameraSceneNodeFPS();
    device.getCursorControl().setVisible(false);
    
    
    device.getGUIEnvironment().addImage(driver.getTexture("media/irrlichtlogoalpha2.tga"),
                                                          new IntVector2D(10,20));
    
    IGUIStaticText diagnostics =
        device.getGUIEnvironment().addStaticText("", new IntRect(10,10,400,20));
    diagnostics.setOverrideColor(new SColor(255, 255, 255, 0));
    
    int lastFPS = -1;
    
    uint then = device.getTimer().getTime();
    
    immutable float MOVEMENT_SPEED = 5.0;
    
    
    while(device.run())
    {
        immutable now = device.getTimer().getTime();
        immutable frameDeltaTime = cast(float)(now - then) / 1000.0;
        then = now;
        
        FloatVector3D nodePosition = node.getPosition();
        
        if(receiver.IsKeyDown(EKEY_CODE.KEY_KEY_W))
            nodePosition.Y = nodePosition.Y + MOVEMENT_SPEED * frameDeltaTime;
        else if(receiver.IsKeyDown(EKEY_CODE.KEY_KEY_S))
            nodePosition.Y = nodePosition.Y - MOVEMENT_SPEED * frameDeltaTime;
            
        if(receiver.IsKeyDown(EKEY_CODE.KEY_KEY_A))
            nodePosition.X = nodePosition.X - MOVEMENT_SPEED * frameDeltaTime;
        else if(receiver.IsKeyDown(EKEY_CODE.KEY_KEY_D))
            nodePosition.X = nodePosition.X + MOVEMENT_SPEED * frameDeltaTime;
            
        node.setPosition(nodePosition);
        
        driver.beginScene(true, true, new SColor(255, 113, 113, 133));
        
        smgr.drawAll();
        
        device.getGUIEnvironment().drawAll();
        
        driver.endScene();
        
        int fps = driver.getFPS();
        
        if(lastFPS != fps)
        {
            wstring tmp = "Movement Example - Irrlicht Engine["w;
            tmp ~= driver.getName();
            tmp ~= "] fps: "w;
            tmp ~= std.conv.to!wstring(fps);
            tmp ~= " in D via SWIG";
            device.setWindowCaption(tmp);
            lastFPS = fps;
        }
    }
}